package com.dj.uphome.web.controller;

import java.io.IOException;
import java.util.List;

import org.mybatis.spring.MyBatisSystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.dj.common.web.rest.ResponsePack;

/**
 * 异常增强，以JSON的形式返回给客服端
 * 异常增强类型：NullPointerException,RunTimeException,ClassCastException, 　　　　　　　　
 * NoSuchMethodException,IOException,IndexOutOfBoundsException 　　　　　　　　
 * 以及springmvc自定义异常等，如下： SpringMVC自定义异常对应的status code Exception HTTP Status Code
 * ConversionNotSupportedException 500 (Internal Server Error)
 * HttpMessageNotWritableException 500 (Internal Server Error)
 * HttpMediaTypeNotSupportedException 415 (Unsupported Media Type)
 * HttpMediaTypeNotAcceptableException 406 (Not Acceptable)
 * HttpRequestMethodNotSupportedException 405 (Method Not Allowed)
 * NoSuchRequestHandlingMethodException 404 (Not Found) TypeMismatchException
 * 400 (Bad Request) HttpMessageNotReadableException 400 (Bad Request)
 * MissingServletRequestParameterException 400 (Bad Request)
 * 
 */

@ControllerAdvice
public class RestExceptionHandler {

	protected Logger logger = LoggerFactory.getLogger(RestExceptionHandler.class);
	/*
	@ModelAttribute
	public PageData getParams() {
		this.
		return new PageData();
	}
*/
	
	// 运行时异常
	@ExceptionHandler(RuntimeException.class)
	@ResponseBody
	public ResponsePack<JSONObject> runtimeExceptionHandler(RuntimeException runtimeException) {
		//runtimeException.printStackTrace();
		logger.debug(runtimeException.getLocalizedMessage());
		return ReturnFormat.retParam(1000, runtimeException.getMessage());
	}

	// 空指针异常
	@ExceptionHandler(NullPointerException.class)
	@ResponseBody
	public ResponsePack<JSONObject> nullPointerExceptionHandler(NullPointerException ex) {
		ex.printStackTrace();
		return ReturnFormat.retParam(1001, null);
	}

	// 类型转换异常
	@ExceptionHandler(ClassCastException.class)
	@ResponseBody
	public ResponsePack<JSONObject> classCastExceptionHandler(ClassCastException ex) {
		ex.printStackTrace();
		return ReturnFormat.retParam(1002, null);
	}

	// IO异常
	@ExceptionHandler(IOException.class)
	@ResponseBody
	public ResponsePack<JSONObject> iOExceptionHandler(IOException ex) {
		ex.printStackTrace();
		return ReturnFormat.retParam(1003, null);
	}
	// 未知方法异常
	@ExceptionHandler(NoSuchMethodException.class)
	@ResponseBody
	public ResponsePack<JSONObject> noSuchMethodExceptionHandler(NoSuchMethodException ex) {
		ex.printStackTrace();
		return ReturnFormat.retParam(1004, null);
	}

	// 数组越界异常
	@ExceptionHandler(IndexOutOfBoundsException.class)
	@ResponseBody
	public ResponsePack<JSONObject> indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
		ex.printStackTrace();
		return ReturnFormat.retParam(1005, null);
	}

	@ExceptionHandler(DataIntegrityViolationException.class)
	@ResponseBody
	public ResponsePack<JSONObject> SqlExceptionHandler(DataIntegrityViolationException ex) {
		ex.printStackTrace();
		return ReturnFormat.retParam(1007, null);
	}
	@ExceptionHandler(DuplicateKeyException.class)
	@ResponseBody
	public ResponsePack<JSONObject> duplicateKeyExceptionHandler(DuplicateKeyException ex) {
		ex.printStackTrace();
		return ReturnFormat.retParam(1008, null);
	}
	@ExceptionHandler(MyBatisSystemException.class)
	@ResponseBody
	public ResponsePack<JSONObject> myBatisSystemExceptionHandler(MyBatisSystemException ex) {
		ex.printStackTrace();
		return ReturnFormat.retParam(1009, null);
	}
	
	// 400错误
	@ExceptionHandler({ HttpMessageNotReadableException.class })
	@ResponseBody
	public ResponsePack<JSONObject> requestNotReadable(HttpMessageNotReadableException ex) {
		System.out.println("400..requestNotReadable");
		ex.printStackTrace();
		return ReturnFormat.retParam(400, null);
	}

	// 400错误
	@ExceptionHandler({ TypeMismatchException.class })
	@ResponseBody
	public ResponsePack<JSONObject> requestTypeMismatch(TypeMismatchException ex) {
		ex.printStackTrace();
		return ReturnFormat.retParam(2001, null);
	}

	// 400错误
	@ExceptionHandler({ MissingServletRequestParameterException.class })
	@ResponseBody
	public ResponsePack<JSONObject> requestMissingServletRequest(
			MissingServletRequestParameterException ex) {
		return ReturnFormat.retParam(2010, null);
	}

	// 405错误
	@ExceptionHandler({ HttpRequestMethodNotSupportedException.class })
	@ResponseBody
	public ResponsePack<JSONObject> request405() {
		System.out.println("405...");
		return ReturnFormat.retParam(405, null);
	}

	// 406错误
	@ExceptionHandler({ HttpMediaTypeNotAcceptableException.class })
	@ResponseBody
	public ResponsePack<JSONObject> request406() {
		System.out.println("404...");
		return ReturnFormat.retParam(406, null);
	}

	// 500错误
	@ExceptionHandler({ ConversionNotSupportedException.class,
			HttpMessageNotWritableException.class })
	@ResponseBody
	public ResponsePack<JSONObject> server500(RuntimeException runtimeException) {
		System.out.println("500...");
		return ReturnFormat.retParam(406, null);
	}

	@ExceptionHandler({ BindException.class })
	@ResponseBody
	public ResponsePack<JSONObject> bindException(BindException bindException) {
		List<ObjectError> list = bindException.getBindingResult()
				.getAllErrors();
		logger.error("错误日志:"+bindException.getMessage());
		if (null != list) {
			StringBuffer sb = new StringBuffer();
			for (ObjectError error : list) {
				FieldError fieldError = (FieldError) error;
				sb.append(fieldError.getDefaultMessage() + ";");
			}
			return ReturnFormat.retParam(2029, sb.toString());
		} else {

			return ReturnFormat.retParam(2029, null);
		}
	}

}